package com.electronic.modules.electronicSealSignature;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.ElectronicSealSignature;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.param.*;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.result.GetAppOperateStatusResultDTO;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.result.GetElectronicSealSignatureUserInfoResultDTO;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.result.GetOriginalTextSignatureValueResultDTO;
import com.cebpubservice.cashare.sdk.electronicsealsignatureandverifysignature.result.UploadSignatureOriginalTextResultDTO;
import com.electronic.appearance.AbstractAppearance;
import com.electronic.appearance.CrossPageAppearance;
import com.electronic.appearance.KeyWordsAppearance;
import com.electronic.appearance.NomalAppearance;
import com.electronic.domain.*;
import com.electronic.enums.*;
import com.electronic.exception.ResultCode;
import com.electronic.exception.ServiceException;
import com.electronic.gbt.GBT6_1_1.SESeal;
import com.electronic.gbt.GBT6_1_2_4.SES_ESPropertyInfo;
import com.electronic.gbt.GBT6_1_2_5.SES_ESPictrueInfo;
import com.electronic.gbt.GBT6_1_2_6.ExtData;
import com.electronic.gbt.GBT6_1_2_6.ExtensionDatas;
import com.electronic.gbt.GBT7_1_1.SES_Signature;
import com.electronic.gbt.GBT7_1_2.TBS_Sign;
import com.electronic.modules.electronicSealSignature.param.StartSignDTO;
import com.electronic.utils.*;
import com.itextpdf.kernel.geom.Rectangle;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: IFCA
 * @Description: 执行签章业务实现类
 */
@Slf4j
@Service
@AllArgsConstructor
public class PdfSignatureGBTService {

    static {
        //添加BC支持
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 测试用例
     */
    private static String testCert = "MIIDFTCCArygAwIBAgIPBslAv+CvdtvpAz1PUBxgMAoGCCqBHM9VAYN1MIGIMQswCQYDVQQGEwJDTjESMBAGA1UECAwJR3VhbmdEb25nMREwDwYDVQQHDAhTaGVuWmhlbjE5MDcGA1UECgwwRGlnaXRhbCBDZXJ0aWZpY2F0ZSBBdXRob3JpemF0aW9uIENlbnRlciBDby4gTHRkMRcwFQYDVQQDDA5HbG9iYWwgU3ViIENBMjAeFw0yMzA3MDcwOTEwNTdaFw0yNDA3MDYwOTEwNTdaMGExCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAnlub/kuJznnIExEjAQBgNVBAcMCea3seWcs+W4gjEqMCgGA1UEAwwh5rex5Zyz5biC5rWL6K+V56eR5oqA5pyJ6ZmQ5YWs5Y+4MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEm3bkCoCaQJxm+zo1hvQnnMt8MLy5+CxukQZ1NBZOTS3cfX5la2fYyGXgRQgj1A2O/m6wN4Pz1Y+nQFSYVnRPEaOCAS0wggEpMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHfjfwKCBeuIUN8/kOEWZ0LG3g+EMB0GA1UdDgQWBBRij3/LGGPBwWaUztDMj13CYrv7ODAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovLzEzOS45Ljg5LjExMjo4MDg1L0dsb2JhbFN1YkNBMi5jcmwwawYIKwYBBQUHAQEEXzBdMCQGCCsGAQUFBzABhhhodHRwOi8vMTM5LjkuODkuMTEyOjgwODIwNQYIKwYBBQUHMAKGKWh0dHA6Ly8xMzkuOS44OS4xMTI6ODA4NS9HbG9iYWxTdWJDQTIuY3J0MAoGCCqBHM9VAYN1A0cAMEQCIGc9hjfu3AAG9O2amxgegmfy2vmw40SyhrpPvcUFrhoGAiBJP5HSOpXsUfMpVKdNopNgLjQZOUry8ondN9jKVhY6rg==";
    private static String testPrivateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgBGo3dacOLVg9J1uGZxZ77QFduzZL+R//vve5v79vSS6gCgYIKoEcz1UBgi2hRANCAASbduQKgJpAnGb7OjWG9Cecy3wwvLn4LG6RBnU0Fk5NLdx9fmVrZ9jIZeBFCCPUDY7+brA3g/PVj6dAVJhWdE8R";

    /**
     * 中招SDK配置
     */
    private final CebsSdkProperties cebsSdkProperties;
    /**
     * 签署属性
     */
    private final SignProperties signProperties;

    /**
     * PDF文件签署
     *
     * @param startSignDTO 签章DOT
     * @param sourcePdf   待签署PDF文件路径
     * @param seSeal      电子印章对象
     * @param accessToken 中招token
     * @param certificate 签名证书
     * @param reason      原因
     * @param location    位置
     */

    public String signature(StartSignDTO startSignDTO,
                            String sourcePdf,
                            SESeal seSeal,
                            String accessToken,
                            Certificate certificate,
                            List<PositionInfo> positionInfoList,
                            String reason,
                            String location,
                            PositionTypeEnum positionTypeEnum

    ) throws Exception {
        //原始文件后缀
        String suffix = FileUtil.getSuffix(sourcePdf);
        //产生的中间文件(临时文件)
        String middleFile = FilePathUtil.generateFileMiddleAbsolutePath(startSignDTO.getSignatureFileSaveFilePath(),startSignDTO.getPid(),suffix);
        //签署完成文件
        String finalFile = FilePathUtil.signatureFileSaveFilePath(startSignDTO.getSignatureFileSaveFilePath(),startSignDTO.getSignatureFileSaveFileName(),suffix);
        //获取第一个位置
        PositionInfo position = positionInfoList.get(0);
        //构造国标签名对象
        PdfGmtSigner pdfGmtSigner = pdfGmtSigner(seSeal, certificate);
        //印章图片
        SES_ESPictrueInfo pictrueInfo = seSeal.geteSealInfo().getPicture();
        // 将 DEROctetString 转换为字节数组
        //印章属性
        SES_ESPropertyInfo propertyInfo = seSeal.geteSealInfo().getProperty();
        //获取印章图片类型
        SealTypeEnum sealTypeEnum = SealTypeEnum.getByType("0"+propertyInfo.getType().toString());
        //对印章图片进行缩放,得到缩放后的图片
        byte[] imgByte = pictrueInfo.getData().getOctets();
        AbstractAppearance appearance = null;
        //重置印章大小
        //构造Rectangle位置
        Rectangle rectangle=null;
        if (Objects.isNull(sealTypeEnum)) {
            rectangle=new Rectangle(position.getPositionX(), position.getPositionY(), 113f, 113f);
            log.info("签章时未获取到印章图片类型{}枚举对象，使用默认图片", propertyInfo.getType().toString());
        } else {
            log.info("印章图片类型{}枚举对象，使用{}", propertyInfo.getType().toString(), sealTypeEnum.getWidthPx() + "*" + sealTypeEnum.getHeightPx());
            rectangle=new Rectangle(position.getPositionX(), position.getPositionY(),sealTypeEnum.getWidthPx(), sealTypeEnum.getHeightPx());
        }
        //骑缝章签署
        if (position.isCrossPage()) {
            appearance = buildCrossPageAppearance(rectangle,sealTypeEnum);
        } else {
            if (PositionTypeEnum.COORD.getType().equals(positionTypeEnum.getType())) {
                //坐标签署
                int[] pageNos = positionInfoList.stream().map(PositionInfo::getPageNo).mapToInt(i -> i).toArray();
                appearance = buildNomalAppearance(pageNos, rectangle);
            } else {
                //关键字签署
                appearance = buildKeyWordsAppearance(positionInfoList, rectangle);
            }
        }
        appearance.setLocation(location);
        appearance.setReason(reason);
        appearance.setStamperSr(imgByte);
        appearance.setTransparency(signProperties.getTransparency());
        //执行签署
        IFCASignature.sign(Paths.get(sourcePdf), Paths.get(middleFile), appearance, pdfGmtSigner.getSignInfoConfig());
        //签名字段名称(合并签署需要)
        String signFieldName = appearance.getSignFieldName();
        //合并签署
        doCombineSign(pdfGmtSigner, signFieldName, seSeal, pdfGmtSigner.getHashValue(), certificate,startSignDTO , accessToken, middleFile, finalFile);
        return finalFile;
    }


    /**
     * 构造骑缝章签名外观
     *
     * @param rectangle 签名位置
     */
    protected AbstractAppearance buildCrossPageAppearance(Rectangle rectangle,SealTypeEnum sealTypeEnum) {
        CrossPageAppearance crossPageAppearance = new CrossPageAppearance();
        crossPageAppearance.setUpperLeftCoordinate(true);
        crossPageAppearance.setMoveCrossPos(true);
        crossPageAppearance.setRectangle(rectangle);
        //自定义透明度
        crossPageAppearance.setTransparency(signProperties.getTransparency());
        crossPageAppearance.setFirstPagePercent(0.2f);
        crossPageAppearance.setLastPagePercent(0.2f);
        if (sealTypeEnum == null){
            //无法获取类型设置为127
            crossPageAppearance.setDpi(127);
            //直接返回
            return crossPageAppearance;
        }
        if (sealTypeEnum.equals(SealTypeEnum.T_01)||sealTypeEnum.equals(SealTypeEnum.T_02)){
            //签章图片高为113时dpi设置(这里设置72可以保证切割的骑缝章图片和原始图片的高度一致)
            crossPageAppearance.setDpi(127);
//            log.info("骑缝章印章图片高为113时dpi设置(113)");
        }else if (sealTypeEnum.equals(SealTypeEnum.T_03)){
            //签章图片高为85时dpi设置(这里设置170可以保证切割的骑缝章图片和原始图片的高度一致)
            crossPageAppearance.setDpi(170);
//            log.info("骑缝章印章图片高为85时dpi设置(这里设置170可以保证切割的骑缝章图片和原始图片的高度一致)");
        }else if (sealTypeEnum.equals(SealTypeEnum.T_00)||sealTypeEnum.equals(SealTypeEnum.T_04)||sealTypeEnum.equals(SealTypeEnum.T_05)||sealTypeEnum.equals(SealTypeEnum.T_06)||sealTypeEnum.equals(SealTypeEnum.T_08)){
            crossPageAppearance.setDpi(253);
//            log.info("类型未知骑缝章印章图片高为57时dpi设置(这里设置233可以保证切割的骑缝章图片和原始图片的高度一致)");
        }else if (sealTypeEnum.equals(SealTypeEnum.T_07)){
            crossPageAppearance.setDpi(1000);
        }

        return crossPageAppearance;
    }

    /**
     * 构造普通签名外观
     *
     * @param rectangle 签名位置
     */
    protected NomalAppearance buildNomalAppearance(int[] pageNos, Rectangle rectangle) {
        //普通签章外观
        NomalAppearance nomalAppearance = new NomalAppearance();
        nomalAppearance.setUpperLeftCoordinate(true);
        nomalAppearance.setRectangle(rectangle);
        nomalAppearance.setDpi(signProperties.getDpi());
        //需要签署的页数
        nomalAppearance.setPagesNums(pageNos);
        return nomalAppearance;
    }

    /**
     * 构造关键字签名外观
     *
     * @param rectangle 签名位置
     */
    protected KeyWordsAppearance buildKeyWordsAppearance(List<PositionInfo> positionInfoList, Rectangle rectangle) {
        //构建每一个关键字签署位置
        List<KeyWordsCoordinate> keyWordsCoordinateList = new ArrayList<>();
        for (PositionInfo positionInfo : positionInfoList) {
            KeyWordsCoordinate keyWordsCoordinate = new KeyWordsCoordinate(positionInfo.getPositionX(), positionInfo.getPositionY(), positionInfo.getPageNo());
            keyWordsCoordinateList.add(keyWordsCoordinate);
        }

        //关键字签章外观
        KeyWordsAppearance keyWordsAppearance = new KeyWordsAppearance();
        keyWordsAppearance.setKeyWordsCoordinate(keyWordsCoordinateList);
        keyWordsAppearance.setRectangle(rectangle);
        keyWordsAppearance.setDpi(signProperties.getDpi());
        //以左下角为原点
        keyWordsAppearance.setUpperLeftCoordinate(false);
        return keyWordsAppearance;
    }


    /**
     * 执行合并签署
     *
     * @param signFieldName 签名字段名称
     * @param seSeal        印章
     * @param dataHash      签名原文
     * @param certificate   签名证书
     * @param startSignDTO   签章DTO
     * @param accessToken   中招token
     * @param middlePdf     临时中间文件
     * @param finalPdf      签署完成最终文件
     * @exception:
     */
    private void doCombineSign(PdfGmtSigner pdfGmtSigner,
                               String signFieldName,
                               SESeal seSeal,
                               byte[] dataHash,
                               Certificate certificate,
                               StartSignDTO startSignDTO,
                               String accessToken,
                               String middlePdf,
                               String finalPdf) throws Exception {
        //构造签章信息 --> 3.数据结构参考国密GBT/38540 7.1.2签章信息
        // 构造 扩展信息
        ExtensionDatas extdatas = new ExtensionDatas();
        log.error("打印开始获取证书链！！！！！！！！！！！！");
        log.error(CertChainsUtil.certificateChain(certificate), "签章结构体证书链");
        //添加证书链
        extdatas.add(new ExtData(
                new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"),
                ASN1Boolean.TRUE,
                new DEROctetString(JSON.toJSONBytes(CertChainsUtil.certificateChain(certificate)))

        ));
        //添加系统硬盘序列号
        extdatas.add(new ExtData(
                new ASN1ObjectIdentifier("1.2.840.113549.1.1.1"),
                ASN1Boolean.TRUE,
                new DEROctetString(JSON.toJSONBytes(SystemUtil.DiskSerialNumber()))

        ));
        //添加系统MAC地址
        extdatas.add(new ExtData(
                new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"),
                ASN1Boolean.TRUE,
                new DEROctetString(JSON.toJSONBytes(SystemUtil.getMacAddress()))

        ));
        //添加CPU序列号
        extdatas.add(new ExtData(
                new ASN1ObjectIdentifier("1.2.840.113549.1.1.3"),
                ASN1Boolean.TRUE,
                new DEROctetString(JSON.toJSONBytes(SystemUtil.getCpuSerialNumber()))

        ));
        //添加IP地址
        extdatas.add(new ExtData(
                new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"),
                ASN1Boolean.TRUE,
                new DEROctetString(JSON.toJSONBytes(SystemUtil.getLocalIpAddress()))

        ));

        TBS_Sign tbsSign = new TBS_Sign()
                .setVersion(seSeal.geteSealInfo().getHeader().getVersion())
                .setEseal(seSeal)
                .setTimeInfo(new ASN1GeneralizedTime(new Date(), Locale.CHINA))
                .setDataHash(dataHash)
                .setPropertyInfo("")
                .setExtDatas(extdatas);

        //待签名原文Base64
        String oriSignDataBase64 = Base64Utils.encodeToString(tbsSign.getEncoded("DER"));
        //待签名原文请求参数
        SignatureOriginalText signatureOriginalText = new SignatureOriginalText();
        signatureOriginalText.setsignatureOriginalTextId(IdUtil.fastSimpleUUID());
        signatureOriginalText.setSignatureOriginalText(oriSignDataBase64);
        //返回的原文签名值
        GetOriginalTextSignatureValueResultDTO signatureValueResultDTO=null;
        try {
             signatureValueResultDTO = getOriginalTextSignatureValue(startSignDTO, accessToken, Arrays.asList(signatureOriginalText));}
        catch (Exception e){
            throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
        }

        //电子签章结构体
        SES_Signature signature = null;
        String signedValue = null;
        if (Objects.isNull(signatureValueResultDTO)) {
            //使用测试用例
            if (signProperties.isEnableTest()) {
                //签章者私钥(测试)
                PrivateKey prvKey = IFCAUtil.getPrivateKey(Base64Utils.decodeFromString(testPrivateKey));
                //签章者证书(测试)
                X509Certificate signCert = IFCAUtil.readX509Certificate(Base64Utils.decodeFromString(testCert));
                //使用私钥签名后的数据(测试)
                byte[] signedByte = GBTSignatureUtil.buildSignedValue(prvKey, Base64Utils.decodeFromString(oriSignDataBase64), pdfGmtSigner.getAlgorithmEnum());
                signedValue = Base64Utils.encodeToString(signedByte);
                //电子签章结构体(测试)
                signature = GBTSignatureUtil.buildSESSignature(tbsSign, Base64Utils.decodeFromString(signedValue), signCert, pdfGmtSigner.getAlgorithmEnum());
            }
        } else {
            //使用私钥签名后的数据(签名值)
            signedValue = signatureValueResultDTO.getSignatureOriginalTextList().get(0).getOriginalTextSignatureValue();
            if (!StringUtils.hasText(signedValue)) {
                log.error("签章业务，中招SDK返回签名值对象中未包含签名值");
                throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
            }
            //电子签章结构体
            signature = GBTSignatureUtil.buildSESSignature(tbsSign, Base64Utils.decodeFromString(signedValue), certificate, pdfGmtSigner.getAlgorithmEnum());
        }
        byte[] signData=null;
        try {
            //TODO 没有签名值
            signData = signature.getEncoded("DER");
        }catch (Exception e){
            throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
        }

        //设置外部电子签名值
        pdfGmtSigner.setExternalSignatureValue(signData);
        //合并外部签名
        IFCASignature.combineExternalSignature(Paths.get(middlePdf), Paths.get(finalPdf), signFieldName, pdfGmtSigner);
    }

    /**
     * 功能描述: 获取原始内容签名值
     *
     * @param startSignDTO      签章对象
     * @param accessToken      中招SDK返回的token
     * @param originalTextList 原始内容
     */
    private GetOriginalTextSignatureValueResultDTO getOriginalTextSignatureValue(
            StartSignDTO startSignDTO,
            String accessToken,
            List<SignatureOriginalText> originalTextList) {
        try {
            // 获取用户信息
            GetElectronicSealSignatureUserInfoParamDTO userInfoParamDTO = new GetElectronicSealSignatureUserInfoParamDTO();
            userInfoParamDTO.setTid(startSignDTO.getTid());
            GetElectronicSealSignatureUserInfoResultDTO electronicSealSignatureUserInfo = ElectronicSealSignature.getElectronicSealSignatureUserInfo(userInfoParamDTO);
            //构造上传待签名原文请求参数
            UploadSignatureOriginalTextParamDTO paramDTO = new UploadSignatureOriginalTextParamDTO();
            paramDTO.setPid(startSignDTO.getPid());
            paramDTO.setTid(startSignDTO.getTid());
            paramDTO.setSealSn(startSignDTO.getSealSn());
            paramDTO.setElectronicSignatureUserType(electronicSealSignatureUserInfo.getSealSignatureUserType());

            if (SealBelongTypeEnum.ENTERPRISE.getType().equals(electronicSealSignatureUserInfo.getSealSignatureUserType())) {
                paramDTO.setOrgTransactionCode(electronicSealSignatureUserInfo.getOrgTransactionCode());
            } else {
                paramDTO.setPersonalTransactionCode(electronicSealSignatureUserInfo.getPersonalTransactionCode());
            }
            paramDTO.setTradingSystemCode(startSignDTO.getCebsSdkProperties().getTradingSystemCode());
            paramDTO.setAccessToken(accessToken);
            //是否连续签章 00:单次签章 、01：连续签章
            paramDTO.setSignContinued(startSignDTO.getSignContinued());
            paramDTO.setSealType(startSignDTO.getSealType());
            //待签名原文请求参数
            paramDTO.setSignatureOriginalTextList(originalTextList);
            //调用SDK获取签名(异步获取签名结果)
            UploadSignatureOriginalTextResultDTO originalTextResultDTO = ElectronicSealSignature.uploadSignatureOriginalText(paramDTO);
            if (Objects.isNull(originalTextResultDTO)) {
                log.error("，调用中招SDK上传待签名原文返回null，请求参数：{}", JSON.toJSONString(paramDTO));
                throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());

            }

            //获取签名值请求参数
            GetOriginalTextSignatureValueParamDTO signatureValueParamDTO = new GetOriginalTextSignatureValueParamDTO();
            signatureValueParamDTO.setTid(originalTextResultDTO.getTid());
            //调用SDK获取签名值
            GetOriginalTextSignatureValueResultDTO signatureValueResultDTO = null;

            //设置检测app状态的入参
            GetAppOperateStatusParamDTO appOperateStatusParamDTO = new GetAppOperateStatusParamDTO();
            appOperateStatusParamDTO.setTid(originalTextResultDTO.getTid());
            //设置检测app状态的出参
            GetAppOperateStatusResultDTO appOperateStatusResultDTO = null;

            //调用SDK重试次数
            AtomicInteger retryNum = new AtomicInteger(signProperties.getRetrySdkNum());
            try {
                while (retryNum.getAndDecrement() > 0) {
                    ICommonUtil.seelp();
                    //暂停2秒后继续查询签名值
                    signatureValueResultDTO = ElectronicSealSignature.getOriginalTextSignatureValue(signatureValueParamDTO);
                    if (Objects.nonNull(signatureValueResultDTO)) {
                        break;
                    }
                    //暂停2秒后继续查询
                    //中招要求先去查询app是否已经退出
                    appOperateStatusResultDTO = ElectronicSealSignature.getAppOperateStatus(appOperateStatusParamDTO);
                    if (Objects.nonNull(appOperateStatusResultDTO) && AppOperateStatusEnum.EXIT.getStatus().equals(appOperateStatusResultDTO.getOperateStatus())) {
//                log.error("Mq业务唯一流水号：{}，调用中招SDK获取签名值，app已退出，请求参数：{}", signatureMq.getTransactionId(), JSON.toJSONString(signatureValueParamDTO));
                        throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
                    }

                }
                if (Objects.isNull(signatureValueResultDTO)) {
                    throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
                }
            }catch (Exception e){
                throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
            }
            return signatureValueResultDTO;
        }catch (Exception e){
            throw new ServiceException(ResultCode.ERROR_USER_LOGIN_EXIT, ResultCode.ERROR_USER_LOGIN_EXIT.getMessage());
        }

    }

    /**
     * 创建国标签名对象
     *
     * @param seSeal      电子印章对象
     * @param certificate 签名证书
     * @return com.cebpubservice.signature.plugin.signature.utils.PdfGmtSigner
     */
    private PdfGmtSigner pdfGmtSigner(SESeal seSeal, Certificate certificate) {
        //签名证书
        Certificate[] chain0 = new Certificate[]{certificate};

        // 获取签名算法的 oid
        String signatureAlgorithmOid = certificate.getPublicKey().getAlgorithm();

        //预估值
        int estimatedSize = 150000;
        //签署配置类
        SignatureConfig signInfo = new SignatureConfig();
        // 判断是否为 SM2 证书
        if (EncryptionAlgorithmConstants.ALGORITHM_EC.equalsIgnoreCase(signatureAlgorithmOid) || EncryptionAlgorithmConstants.ALGORITHM_SM2.equalsIgnoreCase(signatureAlgorithmOid)) {
            signInfo.setAlgorithmType(AlgorithmEnum.SM3);
        } else if (EncryptionAlgorithmConstants.ALGORITHM_RSA.equalsIgnoreCase(signatureAlgorithmOid)) {
//            estimatedSize = 150000;
            signInfo.setAlgorithmType(AlgorithmEnum.SHA256);
        } else {
            throw new ServiceException(ResultCode.ERROR_CERT_ALG_NOT_FOUND, ResultCode.ERROR_CERT_ALG_NOT_FOUND.getMessage());
        }

        signInfo.setPkcs7EstimatedSize(estimatedSize);
        signInfo.setChain(chain0);

        PdfGmtSigner signer = new PdfGmtSigner(signInfo);
        signer.setEstimatedSize(estimatedSize);
        signer.setSeSeal(seSeal);
        signInfo.setGmtSigner(signer);
        return signer;
    }
}
